<script setup lang="ts">
import Dialog from '@/components/Dialog.vue'
import FormTemplate from '@/components/FormTemplate.vue'
import $mitt from '@/common/emitter'
import { IS_FORM_DATA_CHANGE_FN } from '@/common/hooks'
import { Utils } from '@/common/utils.js'
import type {  DialogConfigType  } from '@/components/dialogType'
import type { FormIntType, FormType, FormConfigType } from '@/components/formTemplateType'
import type { FormRules } from 'element-plus'

const emit = defineEmits(['CONFIRM_SUBMIT_EVENT'])
const dialogRef = ref<InstanceType<typeof Dialog>>()
const formTemplateRef = ref<InstanceType<typeof FormTemplate>>()
const formConfig: FormConfigType = {
	labelWidth: '80px',
	formItems: [
		{
			type: 'input',
			key: 'name',
			value: '',
			label: '实例名称',
			placeholder: '请输入实例名称'
		}, {
			type: 'select',
			key: 'deploy_type',
			value: '',
			label: '部署类型',
			placeholder: '请选择部署类型',
			options: [
				{label: '单机', value: 1},
				{label: '温备', value: 2},
				{label: '热备', value: 3}
			]
		}, {
			type: 'select',
			key: 'is_primary',
			value: '',
			label: '主/备',
			placeholder: '请选择',
			options: [
				{label: '主', value: true},
				{label: '备', value: false}
			]
		}, {
			type: 'input',
			key: 'listen_addr',
			value: '',
			label: '监听端口',
			placeholder: '请输入监听端口'
		}, {
			type: 'input',
			key: 'nat_addr',
			value: '',
			label: 'Nat地址',
			placeholder: '请输入Nat地址'
		}, {
			type: 'input',
			key: 'listen_addr_admin',
			value: '',
			label: '管理端口',
			placeholder: '请输入管理端口'
		}
	]
}
const formConfigKey: FormIntType = {}
const formData: FormType = reactive({})
const dialogType = ref('')
let formDataInit: FormType = {}

// 打开弹窗
const exposeOpenDialogAdd_EditFn = (dialogConfig: DialogConfigType) => {
	dialogType.value = dialogConfig.dialogType!
    dialogRef.value?.exposeOpenDialogCommonFn(dialogConfig)
	
	if(dialogConfig.dialogType === 'add') {
		formConfig.formItems?.forEach(item => formConfigKey[item.key] = item.value)
		Object.assign(formData, formConfigKey)
	}
	if(dialogConfig.dialogType === 'edit') Object.assign(formData, dialogConfig.row)

	// 备份初始表单数据，用来比较判断表单是否改动
	formDataInit = Utils.deepCopy(formData)
}
// 关闭弹窗
const exposeCloseDialogAdd_EditFn = () => dialogRef.value?.exposeCloseDialogCommonFn()

// 表单校验
const validateName = (
	rule: any,
	value: any,
	callback: any
) => {
	if(!value) return callback(new Error('请输入实例名称'))
	callback()
}
const validateDeployType = (
	rule: any,
	value: any,
	callback: any
) => {
	if(value === '' || value === undefined) return callback(new Error('请选择部署类型'))
	callback()
}
const validateIsPrimary = (
	rule: any,
	value: any,
	callback: any
) => {
	if(value === '' || value === undefined) return callback(new Error('请选择主备类型'))
	callback()
}
const rules = reactive<FormRules<typeof formData>>({
	name: [
		{required: true, validator: validateName, trigger: 'blur'}
	],
	deploy_type: [
		{required: true, validator: validateDeployType, trigger: 'blur'}
	],
	is_primary: [
		{required: true, validator: validateIsPrimary, trigger: 'blur'}
	]
})

// 提交前的表单校验
const beforeSubmitFn = () => {
	if(IS_FORM_DATA_CHANGE_FN(formDataInit, formData)) return ElMessage.error('表单数据没变化，无法提交')
	// 向index页面发送最终编辑数据
	const formEl = formTemplateRef.value?.formRef
	if(!formEl) return
	formEl.validate(valid => {
		if(!valid) {
			ElMessage.error('表单填写不完整或不符合要求')
			return 
		}
		
		// 校验通过，通知父组件发送提交请求
		emit('CONFIRM_SUBMIT_EVENT', formData)
	})
}

// 暴露给父组件
defineExpose({
    exposeOpenDialogAdd_EditFn,
	exposeCloseDialogAdd_EditFn
})

onMounted(() => {
	// 接收公共dialog组件的确认按钮事件
	$mitt.on('DIALOG_SUBMIT_EVENT', () => beforeSubmitFn())
})
onBeforeUnmount(() => {
	// 销毁事件
	$mitt.all.delete('DIALOG_SUBMIT_EVENT')
})
</script>

<template>
	<Dialog ref="dialogRef">
		<FormTemplate 
			ref="formTemplateRef" 
			v-bind="formConfig" 
			:rules="rules" 
			v-model:formData="formData" 
		/>
	</Dialog>
</template>

<style lang="scss" scoped>
:deep(.el-form) {
	label.el-form-item__label {
		display: inline-block;
		text-indent: 0;
		text-align: right;
	}
}
</style>